package emulator.hardware.io.peripherals;

import emulator.hardware.bits.BitCollector;
import emulator.hardware.bits.BitCollectorAndStrategy;
import emulator.hardware.bits.BitGate;
import emulator.hardware.bits.SharedBit;
import emulator.hardware.io.Port6522;
import emulator.hardware.io.Via6522;

public class KeyboardMatrix {
	private BitGate[] gates = null;
	private SharedBit restore_in;
	
	public void attachToVia(Via6522 via_keyboard, Via6522 via_restore)
	{
		attachToPort(via_keyboard.getPortB(), via_keyboard.getPortA());
		attachRestore(via_restore.getPortA());
	}

	private void attachRestore(Port6522 port) {
		restore_in = port.getControlBit(0);
	}

	public void attachToPort(Port6522 out_port, Port6522 in_port)
	{
		BitCollector[] port_inputs = new BitCollector[8];
		for (int i = 0; i < 8; i++)
		{
			port_inputs[i] = new BitCollector(8, in_port.getInPortBit(i), new BitCollectorAndStrategy());
		}
		
		gates = new BitGate[8];
		for (int i = 0; i < 8; i++)
		{
			gates[i] = new BitGate(8, true);
			for (int j = 0; j < 8; j++)
			{
				gates[i].setOutputBit(j, port_inputs[j].getBitAt(i));
				gates[i].getControlBit(j).setValue(false);
			}
			out_port.setOutPortBit(i, gates[i]);
		}
	}
	
	public void keyDown(int a, int b)
	{
		if (a < 0)
			restore_in.setValue(false);
		else
			gates[b].getControlBit(a).setValue(true);
	}

	public void keyUp(int a, int b)
	{
		if (a < 0)
			restore_in.setValue(true);
		else
			gates[b].getControlBit(a).setValue(false);
	}
}
